package com.bizmda.bizsip.common;

import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONStrFormatter;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * Biz-SIP工具类
 * @author 史正烨
 */
@Slf4j
public class BizUtils {

    private BizUtils() {
    }

    /**
     * 获取当前交易的BizMessage（支持Source、App、Sink层调用）
     * @return 当前交易的BizMessage
     */
    public static BizMessage<JSONObject> getBizMessage() {
        return BizTools.bizMessageThreadLocal.get();
    }

    /**
     * 获取当前交易的控制规则（仅支持App层调用）
     * @return 当前交易的控制规则
     */
    public static JSONObject getControlRule() {
        return BizTools.controlRuleThreadLocal.get();
    }

    /**
     * 设置控制规则后更新标识（true为更新,flase为不更新）
     * @param flag 更新标识（true为更新,flase为不更新）
     */
    public static void setControlRuleUpdatingFlag(boolean flag) {
        JSONObject jsonObject = BizTools.controlRuleThreadLocal.get();
        jsonObject.set(BizConstant.CONTROL_RULE_UPDATING_FLAG,flag);
        BizTools.controlRuleThreadLocal.set(jsonObject);
    }
    /**
     * 构建规范BizMessage对象日志文本
     * @param bizMessage BizMessage对象
     * @return 日志文本
     */
    public static String buildBizMessageLog(BizMessage bizMessage) {
        StringBuilder stringBuilder = new StringBuilder();
        if (!StrUtil.isEmpty(bizMessage.getTraceId())) {
            stringBuilder.append("traceId: " + bizMessage.getTraceId() + "\n");
        }
        if (!StrUtil.isEmpty(bizMessage.getParentTraceId())) {
            stringBuilder.append("parentTraceId: " + bizMessage.getParentTraceId() + "\n");
        }
        stringBuilder.append("appServiceId: " + bizMessage.getAppServiceId() + "\n");
        stringBuilder.append("code: " + bizMessage.getCode() + "\n");
        if (!StrUtil.isEmpty(bizMessage.getMessage())) {
            stringBuilder.append("message: " + bizMessage.getMessage() + "\n");
        }
        if (!StrUtil.isEmpty(bizMessage.getExtMessage())) {
            stringBuilder.append("extMessage: " + bizMessage.getExtMessage() + "\n");
        }
        if (bizMessage.getData() instanceof JSONObject) {
            stringBuilder.append(buildJsonLog(bizMessage.getData()));
        } else if (bizMessage.getData() instanceof byte[]) {
            stringBuilder.append(buildHexLog((byte[]) bizMessage.getData()));
        } else {
            if (bizMessage.getData() != null) {
                stringBuilder.append("<<" + bizMessage.getData().getClass().getName() + ">>:\n");
            }
            stringBuilder.append(bizMessage.getData());
        }

        return stringBuilder.toString();
    }

    /**
     * 构建规范的JSON对象日志文本
     * @param jsonObject JSON对象
     * @return 日志文本
     */
    public static String buildJsonLog(Object jsonObject) {
        if (jsonObject instanceof String) {
            return JSONStrFormatter.format((String) jsonObject);
        } else {
            return JSONUtil.toJsonPrettyStr(jsonObject);
        }
    }

    /**
     * 构建规范的字节流日志文本
     * @param bytes 字节流
     * @return 日志文本
     */
    public static String buildHexLog(byte[] bytes) {
        byte[] rightBytes = new byte[20];
        StringBuilder stringBuilder = new StringBuilder("====+ 01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17-18-19-20 + ====== ASCII  ====== +\n");
        int i;
        for (i = 0; i < bytes.length; i++) {
            if (i % 20 == 0) {
                for (int j = 0; j < 20; j++) {
                    rightBytes[j] = '.';
                }
                stringBuilder.append(StrUtil.fill(String.valueOf(i), '0', 4, true));
                stringBuilder.append(':');
            }
            stringBuilder.append(' ');
            HexUtil.appendHex(stringBuilder, bytes[i], false);
            if (bytes[i] >= 0x20 || bytes[i] < 0) {
                rightBytes[i % 20] = bytes[i];
            }
            if ((i + 1) % 20 == 0) {
                stringBuilder.append(" | ");
                try {
                    appendRightBytes(stringBuilder, rightBytes);
                    stringBuilder.append(" |");
                } catch (BizException e) {
                    e.printStackTrace();
                }
                stringBuilder.append("\n");
            }
        }

        for (int j = i % 20; j < 20; j++) {
            stringBuilder.append("   ");
        }
        if (i % 20 != 0) {

            stringBuilder.append(" | ");
            try {
                appendRightBytes(stringBuilder, rightBytes);
                stringBuilder.append(" |");
            } catch (BizException e) {
                e.printStackTrace();
            }
            stringBuilder.append("\n");
        }
        return stringBuilder.toString();
    }

    private static void appendRightBytes(StringBuilder stringBuilder, byte[] bytes) throws BizException {
        char[] ch = BizTools.getString(bytes).toCharArray();
        for (int i = 0; i < ch.length; i++) {
            stringBuilder.append(ch[i]);
            if (isChinese(ch[i])) {
                stringBuilder.append(".");
            }
        }
        return;
    }

    private static boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);

        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS

                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS

                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A

                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B

                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION

                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS

                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
            return true;
        }
        return false;
    }



}
